<?php

namespace app\common\service;

use app\common\service\DingTalk;

use think\facade\Db;

/**
 * 通知策略接口
 * @param array $data 数据
 * @param array $recipients 接收者
 * @param string $content 内容
 * @param array $jobs 角色
 */
interface NotificationStrategy
{
    public function send(array $data, array $recipients = []): array;
}

/**
 * 抽象通知策略 - 减少重复代码
 */
abstract class BaseNotificationStrategy implements NotificationStrategy
{
    protected $dingTalkService;
    protected $domain;

    public function __construct($dingTalkService, $domain)
    {
        $this->dingTalkService = $dingTalkService;
        $this->domain = $domain;
    }

    /**
     * 发送通知的通用方法
     */
    protected function sendDingTalkNotification(string $title, string $content, string $url = '', array $recipients = []): array
    {
        try {
            $admin_id = Db::name('operator')->where('cname', 'admin')->value('id');
            $recipients = array_filter($recipients, function ($id) use ($admin_id) {
                return $id != $admin_id;
            }); // 删除 admin 用户 , admin 没有钉钉的userid

            return $this->dingTalkService->SendActionCardJobNotificationMessage($title, $content, $url, array_unique($recipients));
        } catch (\Exception $e) {
            \think\facade\Log::error('钉钉通知发送失败: ' . $e->getMessage() . ' 文件：' . $e->getFile() . ' | 行号：' . $e->getLine());
            return ['code' => 500001, 'message' => $e->getMessage()];
        }
    }

    /**
     * 获取指定角色的用户列表
     * @param string $roles 角色ID，多个用逗号分隔，如 '20,10'
     */
    protected function getUsersByRole(string $roles): array
    {
        // 分割角色字符串
        $roleArray = array_filter(explode(',', $roles));

        if (empty($roleArray)) {
            return [];
        }

        $query = Db::name('operator')->where(['is_del' => 0]);

        // 构建 OR 条件：使用 FIND_IN_SET 检查任何一个角色匹配
        $query->where(function ($subQuery) use ($roleArray) {
            foreach ($roleArray as $index => $role) {
                $role = trim($role);
                if ($index === 0) {
                    // 第一个条件用 where
                    $subQuery->whereRaw("FIND_IN_SET('{$role}', job) > 0");
                } else {
                    // 后续条件用 whereOr
                    $subQuery->whereOrRaw("FIND_IN_SET('{$role}', job) > 0");
                }
            }
        });

        $notifyList = $query->field('id')->select()->toArray();

        return array_column($notifyList, 'id');
    }
}

// ==================== 发票相关通知 ====================

/**
 * 发票创建通知
 */
class InvoiceCreatedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['id'])) {
            throw new \InvalidArgumentException('发票ID不能为空');
        }

        $invoice = Db::name('invoice')->where('id', $data['id'])->find();
        if (!$invoice) {
            throw new \Exception('发票信息不存在');
        }

        $order_no = Db::name('order')->where('id', $invoice['order_id'])->value('order_no');
        $url = $this->domain . '/#/order/invoice-management/detail?id=' . $data['id'];
        $recipients = $this->getUsersByRole('20,21'); // 财务角色

        return $this->sendDingTalkNotification(
            '订单开票提醒',
            "订单: {$order_no} 发起了开票请求，请及时处理",
            $url,
            $recipients
        );
    }
}

/**
 * 发票通过通知
 */
class InvoicePassNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['id'])) {
            throw new \InvalidArgumentException('发票ID不能为空');
        }

        $invoice = Db::name('invoice')->where('id', $data['id'])->find();
        if (!$invoice) {
            throw new \Exception('发票信息不存在');
        }

        $order_no = Db::name('order')->where('id', $invoice['order_id'])->value('order_no');
        $url = $this->domain . '/#/order/invoice-management/detail?id=' . $data['id'];
        $recipients = $this->getUsersByRole('1,10,20,21');

        return $this->sendDingTalkNotification(
            '订单开票通过',
            "订单: {$order_no} 开票请求已通过，请及时查收",
            $url,
            $recipients
        );
    }
}

// ==================== 订单相关通知 ====================

/**
 * 订单创建通知
 */
class OrderCreatedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        if (isset($data['owner']) && $data['owner']) {
            $recipients = array_merge($recipients, [$data['owner']]);
        }
        if (isset($data['partner']) && $data['partner']) {
            $recipients = array_merge($recipients, explode(',', $data['partner']));
        }

        $content = "订单：{$data['order_no']} 创建成功，请及时跟进";

        return $this->sendDingTalkNotification('订单提醒', $content, $url, $recipients);
    }
}

/**
 * 订单上传支付凭证通知
 */
class OrderUploadPaymentVoucherNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';
        }
        $transfer_type = isset($data['transfer_type']) ? $data['transfer_type'] : 0;
        switch ($transfer_type) {
            case 1: // Blockchain
                $recipientsJob = $this->getUsersByRole('1,10,21'); //  BOSS 运营主管 财务人员
                break;
            case 2: // Bank Transfer
            case 3: // 银行对公
            case 4: //  微信
            case 5: //  支付宝
                $recipientsJob = $this->getUsersByRole('1,20,21'); // BOSS  财务主管 财务人员
                break;
            case 6: //第三方代收
                $recipientsJob = $this->getUsersByRole('1,10'); //  BOSS 运营主管
                break;
            default:
                $recipientsJob = $this->getUsersByRole('1,10,20,21'); //  BOSS 运营主管 财务主管 财务
                break;
        }
        $recipients = array_merge($recipients, $recipientsJob);
        $content =  "交易流水号：{$data['voucher_code']}\n\n 关联合同号：{$data['order_no']}\n\n 关联合同序号：{$data['id']}\n\n 回款金额：{$data['voucher_pay_amount']}\n\n 支付方式：{$data['payment_method_name']}";
        return $this->sendDingTalkNotification(" 🔥 " . $data['operator'] . "提交了一个回款单", $content, $url, $recipients);
    }
}
/**
 * 订单部分支付通知
 */
class OrderPartialPaidNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';

        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';
        }

        $recipientsJob = $this->getUsersByRole('10,11,12'); //  运营主管 运营 客服
        $recipients = array_merge($recipients, $recipientsJob);

        return $this->sendDingTalkNotification('订单部分支付提醒', '订单号: ' . $data['order_no'] . "\n\n 订单序号：{$data['id']} \n\n ", $url, $recipients);
    }
}

/**
 * 订单支付通知
 */
class OrderPaidNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单支付信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';
        }

        $recipientsJob = $this->getUsersByRole('10,11,12'); //  运营主管 运营 客服
        $recipients = array_merge($recipients, $recipientsJob);

        return $this->sendDingTalkNotification('订单全部支付提醒', '订单号: ' . $data['order_no'] . "\n\n 订单序号：{$data['id']} \n\n ", $url, $recipients);
    }
}

/**
 * 订单支付驳回通知
 */
class OrderPaymentRejectNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {

        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单支付信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '') . '&tab=receipt_management';
        }
        $content = $content ? $content : '订单: ' . $data['order_no'] . ' 支付被驳回，请及时处理';
        return $this->sendDingTalkNotification($data['title'], $content, $url, $recipients);
    }
}

/**
 * 订单发货通知
 */
class OrderDeliveredNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = "您负责的订单：{$data['order_no']} 已全部发货。 \n\n 物流单号：{$data['logistics_no']} \n\n";

        return $this->sendDingTalkNotification('订单提醒', $content, $url, $recipients);
    }
}

/**
 * 订单部分发货通知
 */
class OrderPartialDeliveredNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }


        $content = "您负责的订单：{$data['order_no']} 已部分发货。 \n\n 物流单号：{$data['logistics_no']} \n\n";

        return $this->sendDingTalkNotification('订单提醒', $content, $url, $recipients);
    }
}

/**
 * 订单添加负责人通知
 */
class OrderOwnerAllocatedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = "管理员为您分配了新订单，请及时跟进\n\n";
        $content .= "订单编码：{$data['order_no']}";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单变更负责人通知
 */
class OrderOwnerTransferNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = "您负责的订单已变更负责人，请及时跟进\n\n";
        $content .= "订单编码：{$data['order_no']}";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单变更合伙人通知
 */
class OrderPartnerTransferNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = "您负责的订单已变更合伙人，请及时跟进\n\n";
        $content .= "订单编码：{$data['order_no']}";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单发起退款通知
 */
class OrderInitiateRefundNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['returnorder_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/orderReturn-management/orderReturn/detail?id=' . ($data['id'] ?? '');

        $recipientsJob = $this->getUsersByRole('1,10'); //  BOSS 运营主管
        $recipients = array_merge($recipients, $recipientsJob);

        $content = "您有一个新的退货退款单，请及时审核\n\n";
        $content .= "退款单编码：{$data['returnorder_no']}";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单退款通过通知
 */
class OrderRefundApprovedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['returnorder_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/orderReturn/detail?id=' . ($data['id'] ?? '');

        $content = "您负责的退款单已退款通过，请及时跟进\n\n";
        $content .= "退款单编码：{$data['returnorder_no']}";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单编辑通知
 */
class OrderEditNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = "您负责的订单已编辑，请及时跟进\n\n";
        $content .= "订单编码：{$data['order_no']}";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单取消通知
 */
class OrderCancelNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = $content ? $content : "您负责的订单已取消，请及时跟进\n\n";
        $content .= "订单编码：{$data['order_no']}";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}
/**
 * 订单库存异常通知
 */
class OrderExceptionstatusNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = $content ? $content : "您负责的订单库存异常，请及时跟进\n\n";
        $content .= "订单编码：{$data['order_no']}";

        return $this->sendDingTalkNotification(
            '订单库存异常提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单部分发货申请通知
 */
class OrderPartDeliveryApplyNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '') . '&tab=related_products';
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }
        $recipients = $this->getUsersByRole('1,10'); //  BOSS 运营主管

        $content = $content ? $content : "您有一条新的订单部分发货申请通知，请及时处理\n\n";
        $content .= "订单编码：{$data['order_no']}";

        return $this->sendDingTalkNotification(
            '订单部分发货申请通知',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单待发货通知
 */
class OrderAuditNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = '', string $jobs = ''): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/audit?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/audit?id=' . ($data['id'] ?? '');
        }

        if ($jobs) {
            $recipientsJob = $this->getUsersByRole($jobs);
            $recipients = array_merge($recipients, $recipientsJob);
        }
        $content = $content ? $content : "订单号：{$data['order_no']} \n\n 订单序号：{$data['id']} \n\n ";

        return $this->sendDingTalkNotification(
            '订单审核提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单审核完成通知
 */
class OrderCompleteReviewNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $content = $content ? $content : "订单号：{$data['order_no']} \n\n 订单序号：{$data['id']} \n\n ";

        return $this->sendDingTalkNotification(
            $data['title'],
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单部分发货申请通过通知
 */
class OrderPartDeliveryApplyPassedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }
        $recipientsJob = $this->getUsersByRole('50,51'); // 物流 物流主管
        $recipients = array_merge($recipients, $recipientsJob);
        $content = $content ? $content : "订单{$data['order_no']} 的部分发货申请已经通过，请及时跟进\n\n";

        return $this->sendDingTalkNotification(
            '订单部分发货审批通知',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 订单待发货通知
 */
class OrderDeliveryPendingNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = '', string $jobs = ''): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('订单信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        if ($jobs) {
            $recipientsJob = $this->getUsersByRole($jobs);
            $recipients = array_merge($recipients, $recipientsJob);
        }
        $content = $content ? $content : "订单：{$data['order_no']} 已流转至待发货，请及时跟进。";

        return $this->sendDingTalkNotification(
            '订单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

// ==================== 合同相关通知 ====================

/**
 * 合同创建通知
 */
class ContractCreatedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('合同信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }

        $recipientsJob = $this->getUsersByRole('10,11,12'); //  运营主管 运营 客服
        $recipients = array_merge($recipients, $recipientsJob);
        $content = "订单：{$data['order_no']} 已经生成合同，请下载后及时和客户签署并上传至文件柜。";

        return $this->sendDingTalkNotification(
            '合同提醒',
            $content,
            $url,
            $recipients
        );
    }
}


/**
 * 合同签署通知
 */
class ContractSigningNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['order_no'])) {
            throw new \InvalidArgumentException('合同信息不完整');
        }

        $url = $this->domain . '/#/order/order-management/detail?id=' . ($data['id'] ?? '');
        if (isset($data['order_category']) && 'wholesal' == $data['order_category']) {
            $url = $this->domain . '/#/order/wholesal-order-management/detail?id=' . ($data['id'] ?? '');
        }
        $recipientsJob = $this->getUsersByRole('10,11,12'); //  运营主管 运营 客服
        $recipients = array_merge($recipients, $recipientsJob);
        $content = "订单：{$data['order_no']} 已经完成合同签署。";

        return $this->sendDingTalkNotification(
            '合同提醒',
            $content,
            $url,
            $recipients
        );
    }
}

// ==================== 客户相关通知 ====================

/**
 * 客户分配通知
 */
class CustomerAllocatedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['cusname']) || empty($data['owner'])) {
            throw new \InvalidArgumentException('用户信息不完整');
        }

        $url = $this->domain . '/#/customer/customerList/detail?id=' . ($data['id'] ?? '');

        $content = "管理员为您分配了新客户，请及时跟进\n\n";
        $content .= "客户名称：{$data['cusname']}\n\n";
        if ($data['email'])  $content .= "客户邮箱：{$data['email']}\n\n";
        if ($data['phone'])  $content .= "客户手机：{$data['phone']}";
        return $this->sendDingTalkNotification(
            '客户提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 客户退回通知
 */
class CustomerReturnedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['cusname'])) {
            throw new \InvalidArgumentException('客户信息不完整');
        }
        $url = $this->domain . '/#/customer/customerList/detail?id=' . ($data['id'] ?? '');
        $content = "您负责的客户已被退回公海，请及时跟进\n\n";
        $content .= "客户名称：{$data['cusname']}\n\n";
        if ($data['email'])  $content .= "客户邮箱：{$data['email']}\n\n";
        if ($data['phone'])  $content .= "客户手机：{$data['phone']}";

        return $this->sendDingTalkNotification(
            '客户提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 客户变更负责人通知
 */
class CustomerOwnerTransferNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['cusname'])) {
            throw new \InvalidArgumentException('客户信息不完整');
        }

        $url = $this->domain . '/#/customer/customerList/detail?id=' . ($data['id'] ?? '');
        $content = "您负责的客户已变更负责人，请及时跟进\n\n";
        $content .= "客户名称：{$data['cusname']}\n\n";
        if ($data['email'])  $content .= "客户邮箱：{$data['email']}\n\n";
        if ($data['phone'])  $content .= "客户手机：{$data['phone']}";

        return $this->sendDingTalkNotification(
            '客户提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 客户变更合伙人通知
 */
class CustomerPartnerTransferNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['cusname'])) {
            throw new \InvalidArgumentException('客户信息不完整');
        }

        $url = $this->domain . '/#/customer/customerList/detail?id=' . ($data['id'] ?? '');
        $content = "您负责的客户已变更合作人，请及时跟进\n\n";
        $content .= "客户名称：{$data['cusname']}\n\n";
        if ($data['email'])  $content .= "客户邮箱：{$data['email']}\n\n";
        if ($data['phone'])  $content .= "客户手机：{$data['phone']}";
        return $this->sendDingTalkNotification(
            '客户提醒',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 客户跟进记录创建通知
 */
class CustomerFollowRecordsCreatedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['cusname'])) {
            throw new \InvalidArgumentException('客户信息不完整');
        }

        $url = $this->domain . '/#/customer/customerList/detail?id=' . ($data['id'] ?? '');
        $content = "您负责的客户有新的跟进记录，请及时跟进。\n\n";
        $content .= "跟进内容：{$data['follow_content']}\n\n";
        $content .= "客户名称：{$data['cusname']}\n\n";
        if ($data['email'])  $content .= "客户邮箱：{$data['email']}\n\n";
        if ($data['phone'])  $content .= "客户手机：{$data['phone']}";

        return $this->sendDingTalkNotification(
            '客户提醒',
            $content,
            $url,
            $recipients
        );
    }
}
// ==================== 采购相关通知 ====================

/**
 * 采购订单创建通知
 */
class PurchaseOrderCreatedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['purchase_no'])) {
            throw new \InvalidArgumentException('采购订单信息不完整');
        }

        $url = $this->domain . '/#/purchase/detail?id=' . ($data['id'] ?? '');
        $recipients = $this->getUsersByRole('30'); // 采购角色

        $content = "采购单号：{$data['purchase_no']}\n\n";
        $content .= "采购金额：¥{$data['amount']}\n\n";
        $content .= "供应商：{$data['supplier_name']}\n\n";
        $content .= "申请人：{$data['applicant_name']}\n\n";
        $content .= "时间：" . date('Y-m-d H:i:s');

        return $this->sendDingTalkNotification(
            '新采购订单',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 采购订单审批通知
 */
class PurchaseOrderApprovedNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = []): array
    {
        if (empty($data['purchase_no'])) {
            throw new \InvalidArgumentException('采购订单号不能为空');
        }

        $url = $this->domain . '/#/purchase/detail?id=' . ($data['id'] ?? '');
        $recipients = $this->getUsersByRole('40,20'); // 采购和财务

        $content = "采购单号：{$data['purchase_no']}\n\n";
        $content .= "审批结果：通过\n\n";
        $content .= "审批人：{$data['approver_name']}\n\n";
        $content .= "时间：" . date('Y-m-d H:i:s') . "\n\n";
        $content .= "请及时安排采购和付款！";

        return $this->sendDingTalkNotification(
            '采购订单审批通过',
            $content,
            $url,
            $recipients
        );
    }
}


class PurchasePaymentExamineNotification extends BaseNotificationStrategy
{

    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        $url = $this->domain . '/#/purchase/payment-order-management/detail?id=' . ($data['id'] ?? '');

        $content = $content ? $content : "您有一条采购付款单审核通过，请及时处理：\n\n" . $content;

        return $this->sendDingTalkNotification(
            '采购付款单审核通过',
            $content,
            $url,
            $recipients
        );
    }
}
// ==================== 库存相关通知 ====================

/**
 * 库存校对通知
 */
class InventoryCheckNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = '', string $url = ''): array
    {
        $url = $url ? $url : $this->domain . '/#/warehouse/inventory-management';
        $recipients = $recipients ? $recipients : $this->getUsersByRole('1,10'); // BOSS 和 运营主管

        return $this->sendDingTalkNotification(
            '库存校对',
            $content,
            $url,
            $recipients
        );
    }
}

// ==================== 物流相关通知 ====================


/**
 * 物流规则缺失通知
 */
class MissingLogisticsRuleNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        $url = $this->domain . '/#/logistics/logisticsRules';
        $recipients = $recipients ? $recipients : $this->getUsersByRole('10,50,51'); // 运营主管 物流 物流主管
        $content = $content ? $content : "您有一条新的物流规则缺失通知，请及时处理：\n\n" . $content;

        return $this->sendDingTalkNotification(
            '物流规则缺失',
            $content,
            $url,
            $recipients
        );
    }
}

/**
 * 退货退款单审核通过通知
 */
class ReturnOrderStockNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {


        $url = $this->domain . '/#/orderReturn-management/goodsReturn';
        $recipients = $this->getUsersByRole('50,51'); // 物流主管 物流


        $content = "您有一个新的退货单，请及时跟进\n\n";
        $content .= "退货单编码：{$data['returnorder_no']}";

        return $this->sendDingTalkNotification(
            '退货单提醒',
            $content,
            $url,
            $recipients
        );
    }
}



class ReturnOrderRefundNotification extends BaseNotificationStrategy
{
    public function send(array $data, array $recipients = [], string $content = ''): array
    {
        $url = $this->domain . '/#/orderReturn-management/fundReturn';


        $transfer_type = isset($data['transfer_type']) ? $data['transfer_type'] : 0;
        switch ($transfer_type) {
            case 1: // Blockchain
                $recipientsJob = $this->getUsersByRole('1,10,21'); //  BOSS 运营主管 财务人员
                break;
            case 2: // Bank Transfer
            case 3: // 银行对公
            case 4: //  微信
            case 5: //  支付宝
                $recipientsJob = $this->getUsersByRole('1,20,21'); // BOSS  财务主管 财务人员
                break;
            case 6: //第三方代收
                $recipientsJob = $this->getUsersByRole('1,10'); //  BOSS 运营主管
                break;
            default:
                $recipientsJob = $this->getUsersByRole('1,10,20,21'); //  BOSS 运营主管 财务主管 财务
                break;
        }
        $recipients = array_merge($recipients, $recipientsJob);

        $content = "您有一个新的退款单，请及时跟进\n\n";
        $content .= "退款单编号：{$data['id']}";

        return $this->sendDingTalkNotification(
            '退款单提醒',
            $content,
            $url,
            $recipients
        );
    }
}

// ==================== 通知工厂类 ====================

/**
 * 通知策略工厂
 */
class CompleteNotificationFactory
{
    private $dingTalkService;
    private $domain;

    public function __construct()
    {
        $this->dingTalkService = new DingTalk();
        $this->domain = config()['domain'][env('APP_ENV', 'prod')]['erphome'];
    }

    /**
     * 创建通知策略
     */
    public function create(string $type): NotificationStrategy
    {
        switch ($type) {
            // 发票相关
            case 'invoice_created':
                return new InvoiceCreatedNotification($this->dingTalkService, $this->domain);
            case 'invoice_pass':
                return new InvoicePassNotification($this->dingTalkService, $this->domain);

                // 订单相关
            case 'order_created': // 订单创建
                return new OrderCreatedNotification($this->dingTalkService, $this->domain);
            case 'order_upload_payment_voucher': // 订单上传支付凭证
                return new OrderUploadPaymentVoucherNotification($this->dingTalkService, $this->domain);
            case 'order_partial_payment': // 订单部分支付
                return new OrderPartialPaidNotification($this->dingTalkService, $this->domain);
            case 'order_payment': // 订单支付
                return new OrderPaidNotification($this->dingTalkService, $this->domain);
            case 'order_payment_reject': // 订单支付驳回
                return new OrderPaymentRejectNotification($this->dingTalkService, $this->domain);
            case 'order_delivered': // 订单发货
                return new OrderDeliveredNotification($this->dingTalkService, $this->domain);
            case 'order_partial_delivered': // 订单部分发货
                return new OrderPartialDeliveredNotification($this->dingTalkService, $this->domain);
            case 'order_owner_allocated': // 订单分配负责人
                return new OrderOwnerAllocatedNotification($this->dingTalkService, $this->domain);
            case 'order_owner_transfer': // 订单变更负责人
                return new OrderOwnerTransferNotification($this->dingTalkService, $this->domain);
            case 'order_partner_transfer': // 订单变更合伙人
                return new OrderPartnerTransferNotification($this->dingTalkService, $this->domain);
            case 'order_initiate_refund': // 订单发起退款
                return new OrderInitiateRefundNotification($this->dingTalkService, $this->domain);
            case 'order_refund_approved': // 订单退款通过
                return new OrderRefundApprovedNotification($this->dingTalkService, $this->domain);
            case 'order_edit': // 订单编辑
                return new OrderEditNotification($this->dingTalkService, $this->domain);
            case 'order_audit': // 订单审核
                return new OrderAuditNotification($this->dingTalkService, $this->domain);
            case 'order_complete_review': // 订单完成审核
                return new OrderCompleteReviewNotification($this->dingTalkService, $this->domain);
            case 'order_cancel': // 订单取消
                return new OrderCancelNotification($this->dingTalkService, $this->domain);
            case 'order_exceptionstatus': // 订单异常状态
                return new OrderExceptionstatusNotification($this->dingTalkService, $this->domain);
            case 'order_part_delivery_apply': // 订单部分发货申请
                return new OrderPartDeliveryApplyNotification($this->dingTalkService, $this->domain);
            case 'order_part_delivery_apply_passed': // 订单部分发货申请通过
                return new OrderPartDeliveryApplyPassedNotification($this->dingTalkService, $this->domain);

            case 'order_delivery_pending': // 订单待发货通知
                return new OrderDeliveryPendingNotification($this->dingTalkService, $this->domain);

                //合同相关
            case 'contract_created':
                return new ContractCreatedNotification($this->dingTalkService, $this->domain);
            case 'contract_signing':
                return new ContractSigningNotification($this->dingTalkService, $this->domain);


                // 客户相关
            case 'customer_allocated':
                return new CustomerAllocatedNotification($this->dingTalkService, $this->domain);
            case 'customer_returned':
                return new CustomerReturnedNotification($this->dingTalkService, $this->domain);
            case 'customer_owner_transfer':
                return new CustomerOwnerTransferNotification($this->dingTalkService, $this->domain);
            case 'customer_partner_transfer':
                return new CustomerPartnerTransferNotification($this->dingTalkService, $this->domain);
            case 'customer_follow_records_created':
                return new CustomerFollowRecordsCreatedNotification($this->dingTalkService, $this->domain);

                // 采购相关
            case 'purchase_created':
                return new PurchaseOrderCreatedNotification($this->dingTalkService, $this->domain);
            case 'purchase_order_approved':
                return new PurchaseOrderApprovedNotification($this->dingTalkService, $this->domain);

                // 付款相关
            case 'purchase_payment_examine': // 采购付款单审核
                return new PurchasePaymentExamineNotification($this->dingTalkService, $this->domain);

                // 库存相关
            case 'inventory_check':
                return new InventoryCheckNotification($this->dingTalkService, $this->domain);

                // 物流相关
            case 'missing_logistics_rule':
                return new MissingLogisticsRuleNotification($this->dingTalkService, $this->domain);

                // 退货退款单相关
            case 'return_order_stock':
                return new ReturnOrderStockNotification($this->dingTalkService, $this->domain);
            case 'return_order_refund':
                return new ReturnOrderRefundNotification($this->dingTalkService, $this->domain);

            default:
                throw new \InvalidArgumentException("不支持的通知类型: {$type}");
        }
    }
}

// ==================== 完整通知服务 ====================

/**
 * 完整的通知服务
 */
class CompleteNotificationService
{
    private $factory;

    public function __construct()
    {
        $this->factory = new CompleteNotificationFactory();
    }

    /**
     * 发送通知 - 统一入口
     */
    public function send(string $type, array $data, array $recipients = [], string $content = '', string $jobs = ''): array
    {
        try {
            $strategy = $this->factory->create($type);
            return $strategy->send($data, $recipients, $content, $jobs);
        } catch (\Exception $e) {
            \think\facade\Log::error("通知发送失败 [{$type}]: " . $e->getMessage() . ' 文件：' . $e->getFile() . ' | 行号：' . $e->getLine());
            return ['code' => 500001, 'message' => $e->getMessage()];
        }
    }

    /**
     * 批量发送通知
     */
    public function sendBatch(array $notifications): array
    {
        $results = [];
        foreach ($notifications as $notification) {
            $results[$notification['type']] = $this->send(
                $notification['type'],
                $notification['data'],
                $notification['recipients']
            );
        }
        return $results;
    }

    // 兼容方法
    public function sendInvoiceNotification($event, $data): array
    {
        return $this->send($event, $data);
    }

    public function sendOrderNotification($event, $data): array
    {
        return $this->send($event, $data);
    }

    public function sendUserNotification($event, $data): array
    {
        return $this->send($event, $data);
    }

    public function sendPurchaseNotification($event, $data): array
    {
        return $this->send($event, $data);
    }
}
